package com.zhao.dota.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zhao.dota.bo.AuthenticateUser;
import com.zhao.dota.contant.CacheConstant;
import com.zhao.dota.contant.RoleCodeCont;
import com.zhao.dota.mapper.LeagueMapper;
import com.zhao.dota.model.League;
import com.zhao.dota.model.User;
import com.zhao.dota.model.UserGold;
import com.zhao.dota.security.SecurityUtil;
import com.zhao.dota.service.LeagueService;
import com.zhao.dota.service.UserGoldService;
import com.zhao.dota.service.UserService;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.io.Serializable;
import java.util.List;
import java.util.stream.Collectors;

@Service
@CacheConfig(cacheNames = CacheConstant.LEAGUE)
public class LeagueServiceImpl extends ServiceImpl<LeagueMapper, League> implements LeagueService {

    @Resource
    private UserGoldService userGoldService;
    @Resource
    private UserService userService;

    @Override
    @Transactional
    public int saveLeague(League league) {
        int result = 1;
        if (league.getId() == null) {
            AuthenticateUser authenticateUser = SecurityUtil.getAuthenticateUser();
            league.setCreateUserId(authenticateUser.getId());
            save(league);
            List<User> players = userService.findByRole(RoleCodeCont.PLAYER);
            List<UserGold> goldList = players.stream().map(p -> map(league, p)).collect(Collectors.toList());
            if (!goldList.isEmpty()) {
                userGoldService.saveBatch(goldList);
                result += goldList.size();
            }
        } else {
            league.setCreateUserId(null);
            updateById(league);
        }
        return result;
    }

    private UserGold map(League league, User player) {
        UserGold userGold = new UserGold();
        userGold.setUserId(player.getId());
        userGold.setLeagueId(league.getId());
        userGold.setGold(league.getInitialGold());
        userGold.setInitGold(league.getInitialGold());
        userGold.setDoubleTimes(0);
        userGold.setCaptainModeTimes(0);
        return userGold;
    }

    @Override
    public int addPlayer(User user) {
        int result = 0;
        LambdaQueryWrapper<League> query = Wrappers.lambdaQuery(League.class).eq(League::getEnd, false);
        List<League> leagues = list(query);
        List<UserGold> goldList = leagues.stream().map(league -> map(league, user)).collect(Collectors.toList());
        if (!goldList.isEmpty()) {
            userGoldService.saveBatch(goldList);
            result += goldList.size();
        }
        return result;
    }

    @Override
    @Cacheable(key = "'id:'.concat(#id)", unless = "#result == null")
    public League getById(Serializable id) {
        return baseMapper.selectById(id);
    }
}
